/*
 *	Perlin Production Co. Ltd. September 2012 (c).
 *			FDLib.c
 *		File Descriptor Library
 */
 
#include "stdio.h"
#include "fdlib.h"

FD*	InitFD	(_name)	/* ctor() */
char*	_name;
{
	FD* fd;
	
	if (fd = malloc(sizeof(fdesc)))
	{
		fd->file = ERROR;
		fd->size = fd->bufsiz	= 0;
		fd->buf  = 0;
		fd->name = _name;
		
	} else trouble("allocate file descriptor for", Ptr2Str(_name, "NULL"));
	return fd;
}



FreeFD(_fd)	/* dtor() */
FD* _fd;
{
	CloseFD(_fd);
	free(_fd);
}
	

unsigned SizeFD(_fd)
FD*		_fd;
{
	if (seek(_fd->file,0,LAST) == ERROR)
			trouble("seek LAST in",_fd->name);

	_fd->size = tell(_fd->file);

	if (seek(_fd->file,0,START) == ERROR)
			trouble("seek START in",_fd->name);
	return _fd->size;
}



FILE*	CreatFD(_fd,_mode)
FD*	_fd;
int	_mode;
{
	unlink(_fd->name);

	if ((_fd->file = creat(_fd->name,_mode)) == ERROR)
		trouble("create", _fd->name);
	return _fd->file;
}




FILE*	OpenFD(_fd,_mode)
FD*	_fd;
int	_mode;
{
	if ((_fd->file = open(_fd->name,_mode)) == ERROR)
		trouble("open", _fd->name);
	else SizeFD(_fd);

	return _fd->file;
}



int CloseFD(_fd)
FD*	_fd;
{
	int	result;

	result	= SUCCESS;

	if (_fd->file != ERROR)
	{
		if ((result = close(_fd->file)) == ERROR)
			trouble("close",_fd->name);
			
		_fd->file = ERROR;
		_fd->size = 0;
	}
	
	free(_fd->buf);
	_fd->buf 	= 0;
	_fd->bufsiz	= 0;
	
	return result;
}



char*	ABufFD(_fd, _size,_fill)
FD*		_fd;
unsigned	_size;
char		_fill;
{
	if (_fd->buf)
	{
		trouble("multiple allocation attempts for",_fd->name);
		return 0;
	}
	else
	{
		_fd->buf = malloc(_size);
		if (_fd->buf)
		{
			_fd->bufsiz = _size;
			setmem(_fd->buf,_size,0);
		}
	}
	if (!_fd->buf) trouble("failed to allocate memory for", _fd->name);
	return _fd->buf;
}



seekrd(_fd, _offset, _buf, _size)
FD		*_fd;
unsigned	_offset;
char		*_buf;
unsigned	_size;
{
	char	text[0x100];
	
	if (seek(_fd->file,_offset,START) == ERROR)
	{
		sprintf(text, "seekrd seek(%u) error in", _offset);
		trouble(text,_fd->name);
	}
		
	if ((read(_fd->file, _buf,_size)) != _size)
		trouble("seekrd read error in",_fd->name);
}



seekwrt(_fd, _offset, _buf, _size)
FD		*_fd;
unsigned	_offset;
char		*_buf;
unsigned	_size;
{
	char	text[0x100];
	
	if (seek(_fd->file,_offset,START) == ERROR)
	{
		sprintf(text, "seekwrt seek(%u) error in", _offset);
		trouble(text,_fd->name);
	}
		
	if ((write(_fd->file, _buf,_size)) != _size)
		trouble("seekwrt write error in",_fd->name);
}
